#include <Core.h>
#include "Jump.h"
#include "KeyboardHandle.h"

namespace Jump
{
    bool jump_switch{false};
    HANDLE jump_signal{nullptr};
    bool space_state{false};
    bool ctrl_state{false};
    bool w_state{false};
    unsigned int proc_id{0xffff'ffffu};
    int step_time{25};
}

void Jump::open()
{
    jump_signal = CreateEventW(nullptr,TRUE,FALSE,nullptr);
    jump_switch = true;
    proc_id = KeyboardHandle::add_proc([](WPARAM w,KBDLLHOOKSTRUCT* data){

        if(w == WM_KEYDOWN && !space_state && data->dwExtraInfo == 0ull && data->vkCode == VK_SPACE){
            INFO("<{}><{}><{}>",data->vkCode,data->scanCode,data->dwExtraInfo);
            space_state = true;
        }
        if(w == WM_KEYUP && space_state && data->dwExtraInfo == 0ull && data->vkCode == VK_SPACE){
            INFO("<{}><{}><{}>",data->vkCode,data->scanCode,data->dwExtraInfo);
            space_state = false;
        }
        if(w == WM_KEYDOWN && !ctrl_state && data->dwExtraInfo == 0ull && data->vkCode == VK_LCONTROL){
            INFO("<{}><{}><{}>",data->vkCode,data->scanCode,data->dwExtraInfo);
            ctrl_state = true;
        }
        if(w == WM_KEYUP && ctrl_state && data->dwExtraInfo == 0ull && data->vkCode == VK_LCONTROL){
            INFO("<{}><{}><{}>",data->vkCode,data->scanCode,data->dwExtraInfo);
            ctrl_state = false;
        }
        if(w == WM_KEYDOWN && !w_state && data->dwExtraInfo == 0ull && data->vkCode == 'W'){
            w_state = true;
        }
        if(w == WM_KEYUP && w_state && data->dwExtraInfo == 0ull && data->vkCode == 'W'){
            w_state = false;
        }
        if(space_state )
        {
            SetEvent(jump_signal);
        }else{
            ResetEvent(jump_signal);
        }
    });
    std::thread([](){
        while(jump_switch){
            WaitForSingleObject(jump_signal,INFINITE);
            INFO("Jump");
            keybd_event(VK_SPACE, 57, 0, 1);
            keybd_event(VK_SPACE, 57, KEYEVENTF_KEYUP, 1);
            std::this_thread::sleep_for(std::chrono::milliseconds(step_time));
        }
    }).detach();
}

void Jump::set_step(int time)
{
    step_time = time;
}

int Jump::get_step()
{
    return step_time;
}

void Jump::close()
{
    jump_switch = false;
    CloseHandle(jump_signal);
    KeyboardHandle::remove_proc(proc_id);
    INFO(proc_id);
}
